#include "mystdio.h"


myFILE* my_fopen(const char *path, const char *flag)
{
    int flag1 = 0;
    int iscreate = 0;
    mode_t mode = 0666;
    if(strcmp(flag, "r") == 0)//flag内存的其实就是打开的方式
    {
        flag1 = (O_RDONLY);//默认的iscreate就是0
    }
    else if(strcmp(flag, "w") == 0)
    {
        flag1 = (O_WRONLY | O_CREAT | O_TRUNC);
        iscreate = 1;
    }
    else if(strcmp(flag, "a") == 0)
    {
        flag1 = (O_WRONLY | O_CREAT | O_APPEND);
        iscreate = 1;
    }
    else
    {}

    int fd = 0;
    if(iscreate)
        fd = open(path, flag1, mode);
    else
        fd = open(path, flag1);

    if(fd < 0) return NULL;

    myFILE *fp = (myFILE*)malloc(sizeof(myFILE));
    if(!fp) return NULL;

    fp->fileno = fd;
    fp->flags = FLUSH_LINE;

    fp->cap = LINE_SIZE;
    fp->pos = 0;

    return fp;
}

void my_fflush(myFILE *fp)//刷新缓冲区
{
    write(fp->fileno, fp->cache, fp->pos);//刷新其实就是写入，利用系统调用直接写入内核缓冲区
    fp->pos = 0;
}

ssize_t my_fwrite(myFILE *fp, const char *data, int len)
{
    // 写入操作本质是拷贝, 如果条件允许，就刷新，否则不做刷新
    memcpy(fp->cache+fp->pos, data, len); //从cache的起始位置开始pos个位置，肯定要考虑越界, 自动扩容
    fp->pos += len;                       //将data指向的数据拷贝到fp->cache缓冲区的当前位置fp->pos。字节长度为len。

    if((fp->flags&FLUSH_LINE) && fp->cache[fp->pos-1] == '\n')//进行相与操作，如果非零，那麽就可以证明存在行缓冲；旨在判断是否是行缓冲。后面是判断cache的最后一个位置是否为换行。
    {
        my_fflush(fp);
    }

    return len;
}

void my_fclose(myFILE *fp)
{
    my_fflush(fp);
    close(fp->fileno);//myFILE 结构体中存储的文件描述符;也就是关闭这个文件描述符所对应的文件
    free(fp);//fp 是指向 myFILE 结构体的指针，这个结构体是在 my_fopen 函数中通过 malloc 动态分配内存的,free 函数的作用是释放这个动态分配的内存，避免内存泄漏。
}
  

